﻿using Autofac;
using Autofac.Extensions.DependencyInjection;
using LogDashboard;
using Microsoft.AspNetCore.Authentication.JwtBearer;
using Microsoft.AspNetCore.Builder;
using Microsoft.AspNetCore.Hosting;
using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Mvc;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.FileProviders;
using Microsoft.Extensions.Logging;
using Microsoft.Extensions.Options;
using Microsoft.IdentityModel.Tokens;
using Newtonsoft.Json.Serialization;
using Swashbuckle.AspNetCore.Swagger;
using SXICE.AdminAPI.Filters;
using SXICE.AdminAPI.Infrastructure;
using SXICE.AdminAPI.Middlewares;
using SXICE.AdminAPI.Models;
using SXICE.Core.Helpers;
using SXICE.Core.Infrastructure;
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace SXICE.AdminAPI
{
    public class Startup
    {
        public Startup(IConfiguration configuration)
        {
            Configuration = configuration;
        }

        public IConfiguration Configuration { get; }

        // This method gets called by the runtime. Use this method to add services to the container.
        public IServiceProvider ConfigureServices(IServiceCollection services)
        {
            var containerBuilder = SXICE.Core.Startup.Register();
            containerBuilder.RegisterType<HttpContextAccessor>().As<IHttpContextAccessor>().SingleInstance();   //注册HttpContext访问器
            containerBuilder.RegisterType<Infrastructure.DefaultLocalCache>().As<ILocalCache>().SingleInstance();
            //绑定配置信息
            var jwtSettings = new JwtSettings();
            Configuration.Bind("JwtSettings", jwtSettings);
            containerBuilder.RegisterInstance(jwtSettings);
            //配置Jwt验证
            services.AddAuthentication(options =>
            {
                options.DefaultAuthenticateScheme = JwtBearerDefaults.AuthenticationScheme;
                options.DefaultChallengeScheme = JwtBearerDefaults.AuthenticationScheme;
            }).AddJwtBearer(v =>
            {
                v.TokenValidationParameters = new Microsoft.IdentityModel.Tokens.TokenValidationParameters
                {
                    //Token颁发机构
                    ValidIssuer = jwtSettings.Issuer,
                    //颁发给谁
                    ValidAudience = jwtSettings.Audience,
                    //这里的key要进行加密，需要引用Microsoft.IdentityModel.Tokens
                    IssuerSigningKey = new SymmetricSecurityKey(Encoding.ASCII.GetBytes(jwtSettings.SecretKey)),
                    ValidateIssuerSigningKey = true,
                    //是否验证Token有效期，使用当前时间与Token的Claims中的NotBefore和Expires对比
                    ValidateLifetime = jwtSettings.LifeTime > 0,
                    //允许的服务器时间偏移量
                    ClockSkew = TimeSpan.Zero
                };
            });
            //如果开启了Swagger则配置
            services.AddSwaggerGen(c =>
            {
                c.SwaggerDoc("v1", new Info { Title = "国泰卫康体检后台管理API", Version = "v1" });
                c.OperationFilter<AddAuthTokenHeaderParameter>();
                var file = Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "AdminAPI.xml");
                if (File.Exists(file))
                    c.IncludeXmlComments(file);
            });
            //添加LogDashboard
            services.AddLogDashboard();
            //配置Mvc
            services.AddMvc(options =>
            {
                options.UseCentralRoutePrefix(new RouteAttribute("[controller]/[action]"));
                options.Filters.Add<ValidateNullModelAttribute>();
                options.Filters.Add<AuthorizationRightsAttribute>();
                options.Filters.Add<ExceptionFilter>();
            }).AddJsonOptions(options =>
            {
                options.SerializerSettings.ContractResolver = new DefaultContractResolver();
                options.SerializerSettings.DateFormatString = "yyyy-MM-dd HH:mm:ss";
            })
            .SetCompatibilityVersion(CompatibilityVersion.Version_2_1);
            containerBuilder.Populate(services);
            return new AutofacServiceProvider(RuntimeHelper.Container);
        }

        // This method gets called by the runtime. Use this method to configure the HTTP request pipeline.
        public void Configure(IApplicationBuilder app, IHostingEnvironment env)
        {
            if (env.IsDevelopment())
            {
                app.UseDeveloperExceptionPage();
            }
            app.UseSwaggerUI(c =>
            {
                c.SwaggerEndpoint("/swagger/v1/swagger.json", "WebAPI");
                c.RoutePrefix = "swagger";
            });

            //添加LogDashboard
            app.UseLogDashboard();

            app.UseExceptionHandler(c =>
            {
            });

            app.UseSwagger();

            app.UseExceptionMiddleware();
            //添加验证中间件
            app.UseAuthorizeMiddleware();
            //使用身份校验
            app.UseAuthentication();
            //跨域
            app.UseCors(c =>
            {
                c.AllowAnyOrigin();
                c.AllowAnyHeader();
                c.AllowAnyMethod();
            });
            //使用MVC
            app.UseMvc();
            SXICE.Core.Startup.Init();
            SXICE.Core.Startup.Start();
        }
    }
}